use crate::{runtime::FuncBinds, Env, Value};

use super::Builtin;

pub fn bind(env: &mut FuncBinds) {
    env.bind_builtin("eq", Eq);
    env.bind_builtin("=", Eq);
    env.bind_builtin("not", Not);
}

struct Not;

impl Builtin for Not {
    fn call(&self, _: &Env, argv: &[Value]) -> Result<Value, ()> {
        Ok(match argv {
            [Value::Bool(b)] => Value::Bool(!b),
            _ => {
                eprintln!("not: invalid arguments: {argv:?}");
                return Err(());
            }
        })
    }
}

struct Eq;

impl Builtin for Eq {
    fn call(&self, _: &Env, argv: &[Value]) -> Result<Value, ()> {
        Ok(match argv {
            [lhs, rhs] => Value::Bool(lhs == rhs),
            _ => {
                eprintln!("eq: invalid arguments: {argv:?}");
                return Err(());
            }
        })
    }
}
